package com.fast.util;

import com.wzh.excel.annotation.ExportColumn;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.http.ResponseEntity;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Author zh wang
 * @Create 2025/5/26 20:05
 */
public class ExcelUtil {
    public static <T> ResponseEntity downLoadExcel(List<T> list) {
        if (list == null || list.isEmpty()) {
            return null;
        }
        try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()){
            // 值
            ArrayList<Map<Integer, Object>> valLists = new ArrayList<>();
            handleExportData(list, valLists);

            XSSFWorkbook workbook = createExcel(valLists);

            workbook.write(outputStream);

            return FileUtil.downloadResource(outputStream.toByteArray(), "excel.xlsx");
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    private static XSSFWorkbook createExcel(List<Map<Integer, Object>> valLists) {
        XSSFWorkbook workbook = new XSSFWorkbook();
        workbook.createSheet();
        XSSFSheet sheet = workbook.getSheetAt(0);

        for (int i = 0; i < valLists.size(); i++) {
            Map<Integer, Object> valMap = valLists.get(i);
            if (valMap == null || valMap.isEmpty()) {
                continue;
            }
            XSSFRow row = sheet.createRow(i);
            valMap.forEach((key, value) -> {
                XSSFCell cell = row.createCell(key);
                cell.setCellValue(SecurityUtil.trimDDE(value.toString()));
            });
        }
        return workbook;
    }

    private static <T> void handleExportData(List<T> list, ArrayList<Map<Integer, Object>> valLists) throws IllegalAccessException {
        Field[] fields = list.get(0).getClass().getDeclaredFields();
        valLists.add(null);
        // 表头
        Map<Integer, Object> colNameMap = new HashMap<>();
        for (int i = 0; i < list.size(); i++) {
            // 每行的值
            Map<Integer, Object> valMap = new HashMap<>();
            T data = list.get(i);
            int colIndex = 0;
            for (Field field : fields) {
                ExportColumn exportColumn = field.getAnnotation(ExportColumn.class);
                if (exportColumn != null) {
                    // 下标
                    int order = exportColumn.order();
                    if (order == -1) {
                        order = colIndex;
                        colIndex++;
                    }
                    // 表头列名
                    if (i == 0) {
                        colNameMap.put(order, exportColumn.name());
                    }
                    field.setAccessible(true);
                    // 值
                    valMap.put(order, field.get(data));
                }
            }
            valLists.add(valMap);
        }
        valLists.set(0, colNameMap);
    }
}
